package com.kaiwukj.android.ufamily.mvp.ui.page.service.order;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.alibaba.android.arouter.facade.annotation.Autowired;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.alipay.sdk.app.PayTask;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.StringUtils;
import com.blankj.utilcode.util.TimeUtils;
import com.kaiwukj.android.mcas.di.component.AppComponent;
import com.kaiwukj.android.ufamily.R;
import com.kaiwukj.android.ufamily.app.base.review.BaseMvpActivity;
import com.kaiwukj.android.ufamily.app.constant.ARouterUrlKt;
import com.kaiwukj.android.ufamily.app.constant.Constant;
import com.kaiwukj.android.ufamily.di.component.DaggerOrderComponent;
import com.kaiwukj.android.ufamily.di.module.OrderModule;
import com.kaiwukj.android.ufamily.mvp.http.entity.event.PayEvent;
import com.kaiwukj.android.ufamily.mvp.http.entity.event.PayInfo;
import com.kaiwukj.android.ufamily.mvp.http.entity.event.PayResult;
import com.kaiwukj.android.ufamily.mvp.http.entity.params.OrderCreateParams;
import com.kaiwukj.android.ufamily.mvp.http.entity.params.OrderPayParams;
import com.kaiwukj.android.ufamily.mvp.http.entity.result.MyAddressResult;
import com.kaiwukj.android.ufamily.mvp.http.entity.result.OrderCreateResult;
import com.kaiwukj.android.ufamily.mvp.http.entity.result.ServiceResult;
import com.kaiwukj.android.ufamily.mvp.http.entity.resultbak.AlipayResult;
import com.kaiwukj.android.ufamily.mvp.ui.page.order.OrderContract;
import com.kaiwukj.android.ufamily.mvp.ui.widget.AmountJJLayout;
import com.kaiwukj.android.ufamily.utils.EncryptUtils;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.jaaksi.pickerview.picker.TimePicker;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.Map;

import butterknife.BindView;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

@Route(path = ARouterUrlKt.OrderCreateUrl)
public class OrderCreateActivity extends BaseMvpActivity<OrderCreatePresenter> implements OrderContract.OrderCreateView {

    private static final int PICK_ADDRESS = 101;
    private static final int EDIT_REMARKS = 102;

    @BindView(R.id.tv_title)
    TextView tvTitle;
    @BindView(R.id.tv_address_pick)
    TextView tvAddressPick;
    @BindView(R.id.container_address_detail)
    ViewGroup containerAddressDetail;
    @BindView(R.id.tv_address_detail)
    TextView tvAddressDetail;
    @BindView(R.id.tv_address_phone)
    TextView tvAddressPhone;
    @BindView(R.id.tv_service_type)
    TextView tvServiceType;
    @BindView(R.id.tv_service_time)
    TextView tvServiceTime;
    @BindView(R.id.amount_service)
    AmountJJLayout mAmountJJLayout;
    @BindView(R.id.tv_service_price)
    TextView tvServicePrice;
    @BindView(R.id.tv_fee_avg)
    TextView tvFeeAvg;
    @BindView(R.id.tv_fee_actual)
    TextView tvFeeActual;
    @BindView(R.id.tv_remarks)
    TextView tvRemarks;
    @BindView(R.id.cb_pay_wechat)
    CheckBox cbPayWechat;
    @BindView(R.id.cb_pay_alipay)
    CheckBox cbPayAlipay;

    @BindView(R.id.tv_price)
    TextView tvPrice;


    @Autowired
    ServiceResult.ServiceInfo params;
    @Autowired
    int count = 1;

    private int payWay = 2;//2:wechat 1:alipay

    private MyAddressResult addressResult;
    private String remarks;
    private String serviceTime;//最终时间参数(预约时间)

    private String appointmentTime;

    private int orderId;
    private String orderNo;

    @OnClick(R.id.container_left)
    void onBackClick() {
        onBackPressedSupport();
    }

    @OnClick({R.id.container_address,
            R.id.container_service_time,
            R.id.container_remarks,
            R.id.container_pay_wechat,
            R.id.container_pay_alipay,
            R.id.view_confirm})
    void onViewClick(View v) {
        switch (v.getId()) {
            case R.id.container_address:
                ARouter.getInstance().build(ARouterUrlKt.MyAddressUrl)
                        .withBoolean("isPick", true)
                        .navigation(this, PICK_ADDRESS);
                break;
            case R.id.container_service_time:
                showDatePicker();
                // showTimePicker();
                break;
            case R.id.container_remarks:
                ARouter.getInstance().build(ARouterUrlKt.OrderRemarksUrl)
                        .navigation(this, EDIT_REMARKS);
                break;
            case R.id.container_pay_wechat:
                payWay = 2;
                cbPayAlipay.setChecked(false);
                cbPayWechat.setChecked(true);
                break;
            case R.id.container_pay_alipay:
                payWay = 1;
                cbPayAlipay.setChecked(true);
                cbPayWechat.setChecked(false);
                break;
            case R.id.view_confirm:
                if (addressResult == null) {
                    showMessage("请选择服务地址");
                    return;
                }
                OrderCreateParams reqParams = new OrderCreateParams();
                reqParams.setAddressId(addressResult.getId());
                reqParams.setAppointmentTime(serviceTime);
                reqParams.setNum(count);
                reqParams.setRemarks(remarks);
                reqParams.setServiceParameterId(params.getId());
                mPresenter.createOrder(reqParams);
                showLoading("正在请求...");

                break;
        }
    }

    @Override
    public void setupActivityComponent(@NonNull AppComponent appComponent) {
        super.setupActivityComponent(appComponent);
        DaggerOrderComponent.builder()
                .appComponent(appComponent)
                .orderModule(new OrderModule(this))
                .build().inject(this);
    }

    @Override
    protected int getLayoutId() {
        ARouter.getInstance().inject(this);
        return R.layout.activity_order_create;
    }

    @Override
    protected void initView(Bundle savedInstanceState) {
        tvTitle.setText("提交订单");
        if (params == null) return;
        LogUtils.d("params-------------->" + GsonUtils.toJson(params));
        mAmountJJLayout.setCount(count);
        tvServiceType.setText(params.getParameterName());
        DecimalFormat df = new DecimalFormat("#.##");
        tvPrice.setText(String.format("¥%s", df.format(params.getCharges() * count)));
        tvFeeAvg.setText(String.format("¥%s", df.format(params.getCharges() * count)));
        tvFeeActual.setText(String.format("¥%s", df.format(params.getCharges() * count)));
        tvServicePrice.setText(String.format("¥%s", params.getChargesStr()));
        mAmountJJLayout.setOnCountChangedListener(count -> {
            this.count = count;
            tvPrice.setText(String.format("¥%s", df.format(params.getCharges() * count)));
            tvFeeAvg.setText(String.format("¥%s", df.format(params.getCharges() * count)));
            tvFeeActual.setText(String.format("¥%s", df.format(params.getCharges() * count)));
        });


        int minute = TimeUtils.getValueByCalendarField(System.currentTimeMillis(), Calendar.MINUTE);
        long tempMillis;
        if (minute > 0 && minute <= 30) {
            tempMillis = System.currentTimeMillis() + 1000 * 60 * 60 * 2;
        } else {
            tempMillis = System.currentTimeMillis() + 1000 * 60 * 60 * 3;
        }
        String dateString = mDateFormat03.format(tempMillis);
        String timeString = mDateFormat04.format(tempMillis);

        if (minute > 0 && minute <= 30) {
            appointmentTime = String.format("%s:30", dateString);
            serviceTime = String.format("%s:30:00", timeString);
        } else {
            appointmentTime = String.format("%s:00", dateString);
            serviceTime = String.format("%s:00:00", timeString);
        }

        tvServiceTime.setText(String.format("%s上门", appointmentTime));


    }

    @Override
    protected void initData(Bundle savedInstanceState) {
        mPresenter.getDefAddr();
    }

    public static final SimpleDateFormat mDateFormat =
            new SimpleDateFormat("MM月dd日  E", Locale.CHINA);

    public static final SimpleDateFormat mDateFormat02 =
            new SimpleDateFormat("MM月dd日(E) HH:mm", Locale.CHINA);

    public static final SimpleDateFormat mDateFormat03 =
            new SimpleDateFormat("MM月dd日(E) HH", Locale.CHINA);

    public static final SimpleDateFormat mDateFormat04 =
            new SimpleDateFormat("yyyy-MM-dd HH", Locale.CHINA);

    private void showDatePicker() {
        long startTime = System.currentTimeMillis();
        TimePicker timePicker = new TimePicker.Builder(this,
                TimePicker.TYPE_MIXED_DATE | TimePicker.TYPE_MIXED_TIME, (picker, date) -> {
            serviceTime = TimeUtils.date2String(date);
            appointmentTime = mDateFormat02.format(date);
            String dateString = String.format("%s上门", appointmentTime);
            if (tvServiceTime != null) tvServiceTime.setText(dateString);
        }).setContainsEndDate(true)
                .setFormatter(new TimePicker.DefaultFormatter() {
                    @Override
                    public CharSequence format(TimePicker picker, int type, int position, long value) {
                        if (type == TimePicker.TYPE_MIXED_DATE) {
                            CharSequence text;
                            boolean isToday = TimeUtils.isToday(value);
                            if (isToday) {
                                text = "今天";
                            } else { // xx月xx日 星期 x
                                text = mDateFormat.format(value);
                            }
                            return text;
                        }
                        return super.format(picker, type, position, value);
                    }
                })
                .setTimeMinuteOffset(30)
                .setRangDate(startTime + 1000 * 60 * 60 * 2, startTime + 1000 * 60 * 60 * 24 * 5)
                .create();
        timePicker.show();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PICK_ADDRESS) {
            if (resultCode == RESULT_OK) {
                if (data != null) {
                    showAddress((MyAddressResult) data.getSerializableExtra("addr"));
                }
            }
        } else if (requestCode == EDIT_REMARKS) {
            if (resultCode == RESULT_OK) {
                if (data != null) {
                    remarks = data.getStringExtra("remarks");
                    if (!StringUtils.isEmpty(remarks)) {
                        tvRemarks.setText(remarks);
                    }
                }
            }
        }
    }

    @Override
    public void onOrderCreateResult(OrderCreateResult result) {
        orderId = result.getOrderId();
        orderNo = result.getOrderNum();
        OrderPayParams payParams = new OrderPayParams();
        payParams.setOrderId(result.getOrderId());
        payParams.setOrderNum(result.getOrderNum());
        payParams.setPayType(payWay);
        mPresenter.payOrder(payParams);
    }

    @Override
    public void onOrderPayResult(Map<String, Object> result) {
        hideLoading();
        if (payWay == 1) {
            payByAlipay(GsonUtils.toJson(result));
        } else {
            payByWechat(GsonUtils.toJson(result));
        }
    }

    @Override
    public void onFetchDefAddress(MyAddressResult result) {
        showAddress(result);
    }

    private void showAddress(MyAddressResult result) {
        addressResult = result;
        if (addressResult != null) {
            tvAddressPick.setVisibility(View.GONE);
            containerAddressDetail.setVisibility(View.VISIBLE);
            tvAddressDetail.setText(String.format("%s %s", addressResult.getDetailAddress(), addressResult.getBuildingNumber()));
            tvAddressPhone.setText(String.format("%s %s", addressResult.getConsigneeName(), EncryptUtils.mobileEncrypt(addressResult.getPhone())));
        } else {
            tvAddressPick.setVisibility(View.VISIBLE);
            containerAddressDetail.setVisibility(View.GONE);
        }
    }

    private void payByWechat(String sign) {
        PayInfo payInfo = GsonUtils.fromJson(sign, PayInfo.class);
        final IWXAPI msgApi = WXAPIFactory.createWXAPI(this, null);
        msgApi.registerApp(Constant.WX_APP_ID);
        if (!msgApi.isWXAppInstalled()) {
            showMessage(getString(R.string.please_install_wechat));
            return;
        }
        msgApi.sendReq(payInfo.getPayReq());
    }

    private void payByAlipay(String sign) {
        AlipayResult payObj = GsonUtils.fromJson(sign, AlipayResult.class);
        subscribe(Observable.create((ObservableOnSubscribe<PayResult>) emitter -> {
            PayTask payTask = new PayTask(this);
            Map<String, String> map = payTask.payV2(payObj.getSign(), true);
            emitter.onNext(new PayResult(map));
        }).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(payResult -> {
                    if ("9000".equals(payResult.getResultStatus())) {
                        //EventBus.getDefault().post(new PayEvent(true, 0, "支付成功"));
                        // showMessage("支付成功");
                        onPaySuccess();
                    } else if ("6001".equals(payResult.getResultStatus())) {
                        //cancelOrder(new PayFeeCancelRequest(result.getTradeNo()));
                        showMessage("支付取消");
                    } else {
                        //EventBus.getDefault().post(new PayEvent(false, 0, "支付失败"));
                        showMessage("支付失败:" + payResult.getResultStatus());
                    }
                }));
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onPayEvent(PayEvent payEvent) {
        if (payEvent.isSuccess()) {
            onPaySuccess();
        } else {
            showMessage(payEvent.getDesc());
        }
    }

    private void onPaySuccess() {
        ARouter.getInstance().build(ARouterUrlKt.OrderResultUrl)
                .withInt("type", OrderResultActivity.ORDER_PAY)
                .withInt("orderId", orderId)
                .withString("orderNo", orderNo)
                .withString("appointmentTime", appointmentTime)
                .navigation();
    }
}
